<?php

abstract class Cache_Slot_Abstract extends Dklab_Cache_Frontend_Slot 
{
	
	const REG_KEY_PREFIX = 'smart_';
	
	protected $lifeTime = 864000;	//60*60*24 реальное время жизни данных
	protected $validTime = 3600;	//60*60 период актуальности данных
	protected $trustTime = 60;		//предполагаемое время формирования данных
	
	protected $key = '';
	
	/**
	 * Return backend for caching.
	 * 
	 * @return Zend_Cache_Backend_Interface
	 */
	protected function _getBackend()
	{
		return Cache_Manager::getInstance()->getCleanBackend();
	}
	
	function __construct($key, $time) {
		$this->key = $key;
		$this->lifeTime = $time;
		parent::__construct($this->key, $this->lifeTime);
	}
	
	
	public function smartSave($data, $validTime = 3600) {
		
		//@todo оптимально раскидать время!!!!! важно!!!
		$month = 2592000;
		$time_piece = 43200;//60*60*12
		
		$lifeTime = $this->lifeTime;
		$this->validTime = $validTime;
		
		if ($lifeTime > 0 && ($validTime + $time_piece) > $lifeTime) {	// если $lifeTime не сильно превышает $validTime
			$lifeTime = $validTime + $time_piece;						// сделаем так, чтоб он был больше на 12 часов
		}
		
		if($validTime < $month) {
			$validTime += time();
		}
		if($lifeTime > 0 && $lifeTime < $month) {
			$lifeTime += time();
		}
			
		
		$this->lifeTime = $lifeTime;
		$this->validTime = $validTime;
		
		$keyParams = array(
			'validUntil' => $this->validTime,
			'trustedUntil' => 0
		);
		
		
		//сохранение ключа актуальности данных в кеше
		$keySlot = new Cache_Slot_Array($this->makeRegKey($this->key), $this->lifeTime);
		$keySlot->save($keyParams);
		
		//сохранение данных в кеше. @todo быть может понадобится создавать объект чтобы время изменить.
		$this->_lifetime = $this->lifeTime;
		$this->save($data);
	}
	
	
	public function smartLoad($trustTime = null) {
		//Определение периода доверия
		$trustTime = $trustTime !== null ? $trustTime : $this->trustTime;

		//Получение значения из реестра
		$keySlot = new Cache_Slot_Array($this->makeRegKey($this->key), $this->lifeTime);
		$reg = $keySlot->load();
		
		$currentTime = time();
		
		//поручаем обновить устаревшие данные следующему save-у
		if($trustTime > 0 && (empty($reg) ||
			 empty($reg['trustedUntil']) && $reg['validUntil'] < $currentTime ||
			 !empty($reg['trustedUntil']) && $reg['trustedUntil'] < $currentTime)) {
			$value = false;
			$keyParams = array(
				'validUntil' => 0, 
				'trustedUntil' => ($currentTime + $trustTime)
			);
			$keySlot->save($keyParams);
		} else {
			$value = $this->load();
		}
		
		return $value;
	}
	
	protected function makeRegKey($data) {
		
		$key = self::REG_KEY_PREFIX.$data;
		return $key;
	}
}
